home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / io / PrintStream.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  15.7 KB  |  551 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)PrintStream.java    1.18 98/07/31
  3.  *
  4.  * Copyright 1996-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.io;
  16.  
  17.  
  18. /**
  19.  * A <code>PrintStream</code> adds functionality to another output stream,
  20.  * namely the ability to print representations of various data values
  21.  * conveniently.  Two other features are provided as well.  Unlike other output
  22.  * streams, a <code>PrintStream</code> never throws an
  23.  * <code>IOException</code>; instead, exceptional situations merely set an
  24.  * internal flag that can be tested via the <code>checkError</code> method.
  25.  * Optionally, a <code>PrintStream</code> can be created so as to flush
  26.  * automatically; this means that the <code>flush</code> method is
  27.  * automatically invoked after a byte array is written, one of the
  28.  * <code>println</code> methods is invoked, or a newline character or byte
  29.  * (<code>'\n'</code>) is written.
  30.  *
  31.  * <p> All characters printed by a <code>PrintStream</code> are converted into
  32.  * bytes using the platform's default character encoding.  The <code{@link
  33.  * PrintWriter}</code> class should be used in situations that require writing
  34.  * characters rather than bytes.
  35.  *
  36.  * @version    1.18, 98/07/31
  37.  * @author     Frank Yellin
  38.  * @author     Mark Reinhold
  39.  * @since      JDK1.0
  40.  */
  41.  
  42. public class PrintStream extends FilterOutputStream {
  43.  
  44.     private boolean autoFlush = false;
  45.     private boolean trouble = false;
  46.  
  47.     /**
  48.      * Track both the text- and character-output streams, so that their buffers
  49.      * can be flushed without flushing the entire stream.
  50.      */
  51.     private BufferedWriter textOut;
  52.     private OutputStreamWriter charOut;
  53.  
  54.     /**
  55.      * Create a new print stream.  This stream will not flush automatically.
  56.      *
  57.      * @param  out        The output stream to which values and objects will be
  58.      *                    printed
  59.      *
  60.      * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
  61.      */
  62.     public PrintStream(OutputStream out) {
  63.     this(out, false);
  64.     }
  65.  
  66.     /**
  67.      * Create a new print stream.
  68.      *
  69.      * @param  out        The output stream to which values and objects will be
  70.      *                    printed
  71.      * @param  autoFlush  A boolean; if true, the output buffer will be flushed
  72.      *                    whenever a byte array is written, one of the
  73.      *                    <code>println</code> methods is invoked, or a newline
  74.      *                    character or byte (<code>'\n'</code>) is written
  75.      *
  76.      * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
  77.      */
  78.     public PrintStream(OutputStream out, boolean autoFlush) {
  79.     super(out);
  80.     if (out == null) {
  81.         throw new NullPointerException("Null output stream");
  82.     }
  83.     this.autoFlush = autoFlush;
  84.     this.charOut = new OutputStreamWriter(this);
  85.     this.textOut = new BufferedWriter(this.charOut);
  86.     }
  87.  
  88.     /** Check to make sure that the stream has not been closed */
  89.     private void ensureOpen() throws IOException {
  90.     if (out == null)
  91.         throw new IOException("Stream closed");
  92.     }
  93.  
  94.     /**
  95.      * Flush the stream.  This is done by writing any buffered output bytes to
  96.      * the underlying output stream and then flushing that stream.
  97.      *
  98.      * @see        java.io.OutputStream#flush()
  99.      */
  100.     public void flush() {
  101.     synchronized (this) {
  102.         try {
  103.         ensureOpen();
  104.         out.flush();
  105.         }
  106.         catch (IOException x) {
  107.         trouble = true;
  108.         }
  109.     }
  110.     }
  111.  
  112.     private boolean closing = false; /* To avoid recursive closing */
  113.  
  114.     /**
  115.      * Close the stream.  This is done by flushing the stream and then closing
  116.      * the underlying output stream.
  117.      *
  118.      * @see        java.io.OutputStream#close()
  119.      */
  120.     public void close() {
  121.     synchronized (this) {
  122.         if (! closing) {
  123.         closing = true;
  124.         try {
  125.             textOut.close();
  126.             out.close();
  127.         }
  128.         catch (IOException x) {
  129.             trouble = true;
  130.         }
  131.         textOut = null;
  132.         charOut = null;
  133.         out = null;
  134.         }
  135.     }
  136.     }
  137.  
  138.     /**
  139.      * Flush the stream and check its error state.  The internal error state
  140.      * is set to <code>true</code> when the underlying output stream throws an
  141.      * <code>IOException</code> other than <code>InterruptedIOException</code>,
  142.      * and when the <code>setError</code> method is invoked.  If an operation
  143.      * on the underlying output stream throws an
  144.      * <code>InterruptedIOException</code>, then the <code>PrintStream</code>
  145.      * converts the exception back into an interrupt by doing:
  146.      * <pre>
  147.      *     Thread.currentThread().interrupt();
  148.      * </pre>
  149.      * or the equivalent.
  150.      *
  151.      * @return True if and only if this stream has encountered an
  152.      *         <code>IOException</code> other than
  153.      *         <code>InterruptedIOException</code>, or the
  154.      *         <code>setError</code> method has been invoked
  155.      */
  156.     public boolean checkError() {
  157.     if (out != null)
  158.         flush();
  159.     return trouble;
  160.     }
  161.  
  162.     /**
  163.      * Set the error state of the stream to <code>true</code>.
  164.      *
  165.      * @since JDK1.1
  166.      */
  167.     protected void setError() {
  168.     trouble = true;
  169.     }
  170.  
  171.  
  172.     /*
  173.      * Exception-catching, synchronized output operations,
  174.      * which also implement the write() methods of OutputStream
  175.      */
  176.  
  177.     /**
  178.      * Write the specified byte to this stream.  If the byte is a newline and
  179.      * automatic flushing is enabled then the <code>flush</code> method will be
  180.      * invoked.
  181.      *
  182.      * <p> Note that the byte is written as given; to write a character that
  183.      * will be translated according to the platform's default character
  184.      * encoding, use the <code>print(char)</code> or <code>println(char)</code>
  185.      * methods.
  186.      *
  187.      * @param  b  The byte to be written
  188.      * @see #print(char)
  189.      * @see #println(char)
  190.      */
  191.     public void write(int b) {
  192.     try {
  193.         synchronized (this) {
  194.         ensureOpen();
  195.         out.write(b);
  196.         if ((b == '\n') && autoFlush)
  197.             out.flush();
  198.         }
  199.     }
  200.     catch (InterruptedIOException x) {
  201.         Thread.currentThread().interrupt();
  202.     }
  203.     catch (IOException x) {
  204.         trouble = true;
  205.     }
  206.     }
  207.  
  208.     /**
  209.      * Write <code>len</code> bytes from the specified byte array starting at
  210.      * offset <code>off</code> to this stream.  If automatic flushing is
  211.      * enabled then the <code>flush</code> method will be invoked.
  212.      *
  213.      * <p> Note that the bytes will be written as given; to write characters
  214.      * that will be translated according to the platform's default character
  215.      * encoding, use the <code>print(char)</code> or <code>println(char)</code>
  216.      * methods.
  217.      *
  218.      * @param  buf   A byte array
  219.      * @param  off   Offset from which to start taking bytes
  220.      * @param  len   Number of bytes to write
  221.      */
  222.     public void write(byte buf[], int off, int len) {
  223.     try {
  224.         synchronized (this) {
  225.         ensureOpen();
  226.         out.write(buf, off, len);
  227.         if (autoFlush)
  228.             out.flush();
  229.         }
  230.     }
  231.     catch (InterruptedIOException x) {
  232.         Thread.currentThread().interrupt();
  233.     }
  234.     catch (IOException x) {
  235.         trouble = true;
  236.     }
  237.     }
  238.  
  239.     /*
  240.      * The following private methods on the text- and character-output streams
  241.      * always flush the stream buffers, so that writes to the underlying byte
  242.      * stream occur as promptly as with the original PrintStream.
  243.      */
  244.  
  245.     private void write(char buf[]) {
  246.     try {
  247.         synchronized (this) {
  248.         ensureOpen();
  249.         textOut.write(buf);
  250.         textOut.flushBuffer();
  251.         charOut.flushBuffer();
  252.         if (autoFlush) {
  253.             for (int i = 0; i < buf.length; i++)
  254.             if (buf[i] == '\n')
  255.                 out.flush();
  256.         }
  257.         }
  258.     }
  259.     catch (InterruptedIOException x) {
  260.         Thread.currentThread().interrupt();
  261.     }
  262.     catch (IOException x) {
  263.         trouble = true;
  264.     }
  265.     }
  266.  
  267.     private void write(String s) {
  268.     try {
  269.         synchronized (this) {
  270.         ensureOpen();
  271.         textOut.write(s);
  272.         textOut.flushBuffer();
  273.         charOut.flushBuffer();
  274.         if (autoFlush && (s.indexOf('\n') >= 0))
  275.             out.flush();
  276.         }
  277.     }
  278.     catch (InterruptedIOException x) {
  279.         Thread.currentThread().interrupt();
  280.     }
  281.     catch (IOException x) {
  282.         trouble = true;
  283.     }
  284.     }
  285.  
  286.     private void newLine() {
  287.     try {
  288.         synchronized (this) {
  289.         ensureOpen();
  290.         textOut.newLine();
  291.         textOut.flushBuffer();
  292.         charOut.flushBuffer();
  293.         if (autoFlush)
  294.             out.flush();
  295.         }
  296.     }
  297.     catch (InterruptedIOException x) {
  298.         Thread.currentThread().interrupt();
  299.     }
  300.     catch (IOException x) {
  301.         trouble = true;
  302.     }
  303.     }
  304.  
  305.  
  306.     /* Methods that do not terminate lines */
  307.  
  308.     /**
  309.      * Print a boolean value.  The string produced by <code>{@link
  310.      * java.lang.String#valueOf(boolean)} is translated into bytes according to
  311.      * the platform's default character encoding, and these bytes are written
  312.      * in exactly the manner of the <code>{@link #write(int)} method.
  313.      *
  314.      * @param      b   The <code>boolean</code> to be printed
  315.      */
  316.     public void print(boolean b) {
  317.     write(b ? "true" : "false");
  318.     }
  319.  
  320.     /**
  321.      * Print a character.  The character is translated into one or more bytes
  322.      * according to the platform's default character encoding, and these bytes
  323.      * are written in exactly the manner of the <code>{@link #write(int)}
  324.      * method.
  325.      *
  326.      * @param      c   The <code>char</code> to be printed
  327.      */
  328.     public void print(char c) {
  329.     write(String.valueOf(c));
  330.     }
  331.  
  332.     /**
  333.      * Print an integer.  The string produced by <code>{@link
  334.      * java.lang.String#valueOf(int)} is translated into bytes according to the
  335.      * platform's default character encoding, and these bytes are written in
  336.      * exactly the manner of the <code>{@link #write(int)} method.
  337.      *
  338.      * @param      i   The <code>int</code> to be printed
  339.      * @see        java.lang.Integer#toString(int)
  340.      */
  341.     public void print(int i) {
  342.     write(String.valueOf(i));
  343.     }
  344.  
  345.     /**
  346.      * Print a long integer.  The string produced by <code>{@link
  347.      * java.lang.String#valueOf(long)} is translated into bytes according to
  348.      * the platform's default character encoding, and these bytes are written
  349.      * in exactly the manner of the <code>{@link #write(int)} method.
  350.      *
  351.      * @param      l   The <code>long</code> to be printed
  352.      * @see        java.lang.Long#toString(long)
  353.      */
  354.     public void print(long l) {
  355.     write(String.valueOf(l));
  356.     }
  357.  
  358.     /**
  359.      * Print a floating-point number.  The string produced by <code>{@link
  360.      * java.lang.String#valueOf(float)} is translated into bytes according to
  361.      * the platform's default character encoding, and these bytes are written
  362.      * in exactly the manner of the <code>{@link #write(int)} method.
  363.      *
  364.      * @param      f   The <code>float</code> to be printed
  365.      * @see        java.lang.Float#toString(float)
  366.      */
  367.     public void print(float f) {
  368.     write(String.valueOf(f));
  369.     }
  370.  
  371.     /**
  372.      * Print a double-precision floating-point number.  The string produced by
  373.      * <code>{@link java.lang.String#valueOf(double)} is translated into bytes
  374.      * according to the platform's default character encoding, and these bytes
  375.      * are written in exactly the manner of the <code>{@link #write(int)}
  376.      * method.
  377.      *
  378.      * @param      d   The <code>double</code> to be printed
  379.      * @see        java.lang.Double#toString(double)
  380.      */
  381.     public void print(double d) {
  382.     write(String.valueOf(d));
  383.     }
  384.  
  385.     /**
  386.      * Print an array of characters.  The characters are converted into bytes
  387.      * according to the platform's default character encoding, and these bytes
  388.      * are written in exactly the manner of the <code>{@link #write(int)}
  389.      * method.
  390.      *
  391.      * @param      s   The array of chars to be printed
  392.      * 
  393.      * @throws  NullPointerException  If <code>s</code> is <code>null</code>
  394.      */
  395.     public void print(char s[]) {
  396.     write(s);
  397.     }
  398.  
  399.     /**
  400.      * Print a string.  If the argument is <code>null</code> then the string
  401.      * <code>"null"</code> is printed.  Otherwise, the string's characters are
  402.      * converted into bytes according to the platform's default character
  403.      * encoding, and these bytes are written in exactly the manner of the
  404.      * <code>{@link #write(int)} method.
  405.      *
  406.      * @param      s   The <code>String</code> to be printed
  407.      */
  408.     public void print(String s) {
  409.     if (s == null) {
  410.         s = "null";
  411.     }
  412.     write(s);
  413.     }
  414.  
  415.     /**
  416.      * Print an object.  The string produced by the <code>{@link
  417.      * java.lang.String#valueOf(Object)} method is translated into bytes
  418.      * according to the platform's default character encoding, and these bytes
  419.      * are written in exactly the manner of the <code>{@link #write(int)}
  420.      * method.
  421.      *
  422.      * @param      obj   The <code>Object</code> to be printed
  423.      * @see        java.lang.Object#toString()
  424.      */
  425.     public void print(Object obj) {
  426.     write(String.valueOf(obj));
  427.     }
  428.  
  429.  
  430.     /* Methods that do terminate lines */
  431.  
  432.     /**
  433.      * Terminate the current line by writing the line separator string.  The
  434.      * line separator string is defined by the system property
  435.      * <code>line.separator</code>, and is not necessarily a single newline
  436.      * character (<code>'\n'</code>).
  437.      */
  438.     public void println() {
  439.     newLine();
  440.     }
  441.  
  442.     /**
  443.      * Print a boolean and then terminate the line.  This method behaves as
  444.      * though it invokes <code>{@link #print(boolean)} and then <code>{@link
  445.      * #println()}</code>.
  446.      */
  447.     public void println(boolean x) {
  448.     synchronized (this) {
  449.         print(x);
  450.         newLine();
  451.     }
  452.     }
  453.  
  454.     /**
  455.      * Print a character and then terminate the line.  This method behaves as
  456.      * though it invokes <code>{@link #print(char)} and then <code>{@link
  457.      * #println()}</code>.
  458.      */
  459.     public void println(char x) {
  460.     synchronized (this) {
  461.         print(x);
  462.         newLine();
  463.     }
  464.     }
  465.  
  466.     /**
  467.      * Print an integer and then terminate the line.  This method behaves as
  468.      * though it invokes <code>{@link #print(int)} and then <code>{@link
  469.      * #println()}</code>.
  470.      */
  471.     public void println(int x) {
  472.     synchronized (this) {
  473.         print(x);
  474.         newLine();
  475.     }
  476.     }
  477.  
  478.     /**
  479.      * Print a long and then terminate the line.  This method behaves as
  480.      * though it invokes <code>{@link #print(long)} and then <code>{@link
  481.      * #println()}</code>.
  482.      */
  483.     public void println(long x) {
  484.     synchronized (this) {
  485.         print(x);
  486.         newLine();
  487.     }
  488.     }
  489.  
  490.     /**
  491.      * Print a float and then terminate the line.  This method behaves as
  492.      * though it invokes <code>{@link #print(float)} and then <code>{@link
  493.      * #println()}</code>.
  494.      */
  495.     public void println(float x) {
  496.     synchronized (this) {
  497.         print(x);
  498.         newLine();
  499.     }
  500.     }
  501.  
  502.     /**
  503.      * Print a double and then terminate the line.  This method behaves as
  504.      * though it invokes <code>{@link #print(double)} and then <code>{@link
  505.      * #println()}</code>.
  506.      */
  507.     public void println(double x) {
  508.     synchronized (this) {
  509.         print(x);
  510.         newLine();
  511.     }
  512.     }
  513.  
  514.     /**
  515.      * Print an array of characters and then terminate the line.  This method
  516.      * behaves as though it invokes <code>{@link #print(char[])} and then
  517.      * <code>{@link #println()}</code>.
  518.      */
  519.     public void println(char x[]) {
  520.     synchronized (this) {
  521.         print(x);
  522.         newLine();
  523.     }
  524.     }
  525.  
  526.     /**
  527.      * Print a String and then terminate the line.  This method behaves as
  528.      * though it invokes <code>{@link #print(String)} and then <code>{@link
  529.      * #println()}</code>.
  530.      */
  531.     public void println(String x) {
  532.     synchronized (this) {
  533.         print(x);
  534.         newLine();
  535.     }
  536.     }
  537.  
  538.     /**
  539.      * Print an Object and then terminate the line.  This method behaves as
  540.      * though it invokes <code>{@link #print(Object)} and then <code>{@link
  541.      * #println()}</code>.
  542.      */
  543.     public void println(Object x) {
  544.     synchronized (this) {
  545.         print(x);
  546.         newLine();
  547.     }
  548.     }
  549.  
  550. }
  551.